package com.cc.visitor.service;

import com.cc.alltype.BusinessException;
import com.cc.alltype.StringUtils;
import com.cc.visitor.dao.TemplateMsgDetailMapper;
import com.cc.visitor.dao.TemplateMsgMainMapper;
import com.cc.visitor.entity.TemplateMsg;
import com.cc.visitor.entity.TemplateMsgDetail;
import com.cc.visitor.entity.wechat.WxAccessToken;
import com.cc.visitor.entity.wechat.templateMessage.MiniProgram;
import com.cc.visitor.enums.DevMaterial;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author chanchaw
 * @create 2024-12-02 19:34
 */
@Service
public class TemplateMsgServiceImpl implements TemplateMsgService{
    private ObjectMapper mapper = new ObjectMapper();
    @Autowired
    private WxAccessToken wxAccessToken;
    @Autowired
    private TemplateMsgMainMapper mainMapper;
    @Autowired
    private TemplateMsgDetailMapper detailMapper;

    @Override
    public TemplateMsg select8Name(String sname){
        sname = Optional.ofNullable(sname).orElse("");
        TemplateMsg templateMsg = mainMapper.select8Name(sname);
        if(templateMsg == null) throw new BusinessException("没有找到[" + sname + "]的模板消息");
        List<TemplateMsgDetail> detailList = detailMapper.select8ParentId(templateMsg.getId());
        templateMsg.setDetailList(detailList);
        return templateMsg;
    }
    @Override
    public TemplateMsg select8TemplateId(String templateId) {
        templateId = Optional.ofNullable(templateId).orElse("");
        TemplateMsg templateMsg = mainMapper.select8TemplateId(templateId);
        if(templateMsg == null) throw new BusinessException("没有找到" + templateId + "的模板消息");
        List<TemplateMsgDetail> detailList = detailMapper.select8TemplateId(templateId);
        templateMsg.setDetailList(detailList);
        return templateMsg;
    }

    @Override
    public List<Map<String,Object>> getItemMapList(String templateId, List<Object> dataList){
        List<TemplateMsgDetail> detailList = detailMapper.select8TemplateId(templateId);
        if(detailList == null || detailList.size() == 0) throw new BusinessException("没有找到" + templateId + "模板消息的数据体明细配置项！");
        if(detailList.size() != dataList.size()) throw new BusinessException("模板消息明细配置表中要求元素个数" + detailList.size() +
                "，但是传入数据为" + dataList.size() + "个！");
        List<Map<String,Object>> ret = new ArrayList<>();
        for (int i = 0; i < detailList.size(); i++) {
            Map<String,Object> map = new HashMap<>();
            map.put(detailList.get(i).getItemName(), dataList.get(i));
            ret.add(map);
        }
        return ret;
    }

    /**
     * 构建用于推送模板消息的 map 对象
     * @param sname template_msg_main中的模板名称
     * @param openId 接受模板消息的微信 openId
     * @param url 点击后跳转的URL
     * @param miniProgramPath 点击后跳转的小程序页面路径，一般为：pages/register/register
     * @param itemDataList 填充到模板每个项目的数据
     * @return 该 map 对象可直接用于推送模板消息
     * @throws Exception
     */
    @Override
    public Map<String, Object> getTemplateMsgMap(String sname, String openId, String url, String miniProgramPath,
                                                 List<Object> itemDataList) {

        TemplateMsg templateMsg = select8Name(sname);
        String templateId = Optional.ofNullable(templateMsg.getTemplateId()).orElse("");

        Map<String,Object> msg = new HashMap<>();
        msg.put("touser",openId);
        msg.put("template_id",templateId);
        msg.put("url",url);

        msg.put("miniprogram", null);
        if(miniProgramPath.length() > 0){
            MiniProgram miniProgram = new MiniProgram();
            miniProgram.setAppid(DevMaterial.VISITOR_MINI.APPID);
            miniProgram.setPagepath(miniProgramPath);
            msg.put("miniprogram", miniProgram);
        }

        if(templateMsg == null) throw new BusinessException("没有找到id:" + templateId + "的模板消息！");
        if(!templateMsg.getItemQty().equals(itemDataList.size())) throw new BusinessException("配置表要求要素数量" + templateMsg.getItemQty() +
                "，传入的填充数据是" + itemDataList.size() + "个，不匹配！");

        Map<String,Object> itemDataMap = new HashMap<>();
        for (int i = 0; i < templateMsg.getItemQty(); i++) {
            Map<String,Object> tmpMap = new HashMap<>();

            // 2025年3月18日 14:15:21 添加字段 template_msg_detail.len
            // 发送模板消息前截取每个项目的长度，保证长度合法
            String strData = itemDataList.get(i).toString();
            Integer len = Optional.ofNullable(templateMsg.getDetailList().get(i).getLen()).orElse(0);
            if(len > 0) strData = StringUtils.left(strData,len);

            tmpMap.put("value", strData);
            itemDataMap.put(templateMsg.getDetailList().get(i).getItemName(), tmpMap);
        }
        msg.put("data", itemDataMap);
        return msg;
    }

    /**
     * 根据订阅消息的名称构建消息对象
     * @param sname 订阅消息模板的名称
     * @param openId 小程序 openId
     * @param itemDataList 消息的内容对象
     * @return
     */
    @Override
    public Map<String, Object> getMiniMsgMap(String sname, String openId, List<Object> itemDataList){
        TemplateMsg templateMsg = select8Name(sname);
        String templateId = Optional.ofNullable(templateMsg.getTemplateId()).orElse("");
        if(templateMsg == null) throw new BusinessException("没有找到id:" + templateId + "的模板消息！");

        Map<String,Object> msg = new HashMap<>();
        msg.put("access_token", DevMaterial.VISITOR_MINI.TOKEN);
        msg.put("template_id",templateId);
        msg.put("touser",openId);
        msg.put("miniprogram_state","formal");// 推送给正式版小程序客户端
        msg.put("lang","zh_CN");
        if(!templateMsg.getItemQty().equals(itemDataList.size())) throw new BusinessException("配置表要求要素数量" + templateMsg.getItemQty() +
                "，传入的填充数据是" + itemDataList.size() + "个，不匹配！");

        Map<String,Object> itemDataMap = new HashMap<>();
        for (int i = 0; i < templateMsg.getItemQty(); i++) {
            Map<String,Object> tmpMap = new HashMap<>();
            tmpMap.put("value", itemDataList.get(i));
            itemDataMap.put(templateMsg.getDetailList().get(i).getItemName(), tmpMap);
        }
        msg.put("data", itemDataMap);
        return msg;
    }
}
